package com.weishaoying.example.security.config;

import com.weishaoying.example.security.service.CustomerUserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;

/**
 * @author WeiShaoying
 * @date 2018/4/3
 */
//@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    //配置Security的Filter链
    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

    //private DataSource dataSource;

    @Bean
    UserDetailsService customerUserService() {
        return new CustomerUserService();
    }

    //用户认证，通俗的说就是用户登录，所以需要一套存储用户信息的数据源，支持3种方式
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //1.使用内存数据源，适合开发测试
        auth.inMemoryAuthentication()
                .withUser("admin").password("admin").roles("ADMIN")
                .and()
                .withUser("rose").password("abc123").roles("USER")
                .and()
                .withUser("lily").password("abc456").roles("GUEST");

        //2.支持JDBC数据源,只需要配置数据源即可，看似简单却不灵活，因为security规定表结构
        //auth.jdbcAuthentication().dataSource(dataSource);

        //3.自定义,可以操作DB,NoSQL,JPA等，最灵活
        auth.userDetailsService(customerUserService());

    }

    //配置认证的细节
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        http
//                .authorizeRequests()//通过它开始请求权限配置
//                .antMatchers("/admin/**").hasRole("ADMIN")//只有拥有admin角色才能访问/admin/**
//                .antMatchers("/user/**").hasAnyRole("ADMIN", "USER")//拥有两个角色中的一个就能访问/user/**
//                .anyRequest()//其它所有请求
//                .authenticated();//必须认证(登录)后才能访问

        //这样会导致 http://localhost:8080/ 都会报403

//        http
//                .formLogin()//指定支持基于表单的认证
//                .loginPage("/login")//如果没有配置这个，将会生成默认的登录页，如开始时所看到的
//                .defaultSuccessUrl("/index")//登录成功后转向页面
//                .failureUrl("/login?error")//失败后转向页面
//                .permitAll()//允许所有人访问登录页
//                .and()
//                .rememberMe()//开启记住我，即：cookie存储用户信息
//                .tokenValiditySeconds(600)//10分钟
//                .key("pin")
//                .and()
//                .logout()//定制注销行为
//                .logoutUrl("/logout2")//指定注销URL
//                .logoutSuccessUrl("/logout-success")//注销成功后转向页面
//                .permitAll();//允许所有人访问注销

        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()//支持基于表单的认证
                .loginPage("/login")//指定登录URL
                .failureUrl("/login?error")
                .permitAll()
                .and()
                .logout()
                .permitAll();
    }
}
